<template>
  <ArtTableFullScreen>
    <div class="account-page" :style="{ height: containerMinHeight}" id="table-full-screen">
 	  <ArtRuleSearchForm 
			ref="userArtRuleSearchFormRef"
			:rule="'visual-component-library-query-form'" 
			:showExpand="true"
			@reset="handleReset"
			@search="handleSearch"
	  ></ArtRuleSearchForm> 

      <ElCard shadow="never" class="art-table-card" style="height: calc(100vh - 214px);">
		<div style="height: calc(100% - 0px);">
			<ArtRuleTable 
				ref="userArtRuleTableRef"
				row-key="id"
				rule="visual-component-library-table" 
				:hideOnSinglePage="false"
				:fetch-data="fetchComponentLibraryData" 
				:autoLoad="true"
				:customFormatters="customFormatters"
				:customToolBars="getToolBarFormatters"
				paginationAlign="right"
				></ArtRuleTable>
		</div>
    <ElDialog
          v-model="dialogVisible"
          :title="dialogType === 'add' ? '添加组件' : '编辑组件'"
          width="50%"
          align-center
		  :close-on-click-modal="false"
		  draggable
        >

		<ElForm ref="formRef" :model="formData" :rules="rules" label-width="120px">
          <ElFormItem label="缩略图" prop="thumbnail">
            <div class="avatar-upload-wrapper">
              <ElUpload
                class="avatar-uploader"
                ref="upload"
                :auto-upload="false"
                :show-file-list="false"
                :on-change="handleChange"
                :before-upload="beforeUpload"
                accept="image/*"
              >
                <div v-if="imageUrl" class="avatar-img-box" @mouseenter="hovering=true" @mouseleave="hovering=false">
                  <img
                    :src="imageUrl"
                    class="avatar"
                    width="120"
                    height="120"
                    @click="handlePreview"
                  >
                  <el-button
                    v-if="hovering"
                    class="avatar-remove-btn"
                    type="danger"
                    size="small"
                    @click.stop="removeImage"
                  >移除</el-button>
                </div>
                <div v-else class="avatar-upload-placeholder">
                  <el-icon class="avatar-uploader-icon"><Plus /></el-icon>
                  <div class="avatar-upload-text">上传图片</div>
                </div>
              </ElUpload>
            </div>
          </ElFormItem>

            <ElFormItem label="组件名称" prop="name">
              <ElInput v-model="formData.name" />
            </ElFormItem>
            <ElFormItem label="组件分类" prop="category">
              <ElSelect v-model="formData.category"> 
                  <ElOption :label="category.cnLabel" :value="category.value" :key="category.id"  v-for="category in categories"  />           
                </ElSelect>
            </ElFormItem>

            <ElFormItem label="组件类型" prop="type">
              <ElInput v-model="formData.type" />
            </ElFormItem>

            <ElFormItem label="组件路径" prop="path">
              <ElInput v-model="formData.path" />
            </ElFormItem>

            <ElFormItem label="组件配置" prop="configPath">
              <ElInput v-model="formData.configPath" />
            </ElFormItem>

            <ElFormItem label="组件描述" prop="description">
              <ElInput v-model="formData.description" type="textarea" :rows="3" />
            </ElFormItem>

          </ElForm>


          <template #footer>
            <div class="dialog-footer">
              <ElButton @click="dialogVisible = false">取消</ElButton>
              <ElButton type="primary" @click="handleSubmit">提交</ElButton>
            </div>
          </template>
        </ElDialog>
      </ElCard>
    <EditDataModelDialog
      ref="editDataModelDialogRef"
      v-if="editDataModelDialogVisible"
      @closeDialog="editDataModelDialogVisible = false"
    />
    </div>
  </ArtTableFullScreen>
</template>

<script setup lang="ts">
  import { h } from 'vue'
  import { ElDialog, FormInstance, ElTag, ElMessageBox, ElMessage } from 'element-plus'
  import type { FormRules } from 'element-plus'
  import ArtButtonTable from '@/components/core/forms/ArtButtonTable.vue'
  import { ComponentLibraryService } from '@/api/visual/componentLibraryApi'
  import { DictService } from '@/api/sys/dictApi'
  import ArtRuleTable from '@/components/custom/table/ArtRuleTable.vue'
  import ArtRuleSearchForm from '@/components/custom/forms/ArtRuleSearchForm.vue'
  import { useCommon } from '@/composables/useCommon'
  import EditDataModelDialog from './widgets/EditDataModelDialog.vue'
  import { nextTick, computed } from 'vue'
  import { axiosInstance } from '@/utils/http/index'
  import { objectToFormData } from '@/utils/form/form'
  import { toRaw } from 'vue'
  const { containerMinHeight } = useCommon()
  const { width } = useWindowSize()
  defineOptions({ name: 'ComponentLibrary' }) // 定义组件名称，用于 KeepAlive 缓存控制

  const dialogType = ref('add')
  const dialogVisible = ref(false)
  const loading = ref(false)

  // 响应式表单数据
  const formFilters = reactive({})

  // 选中的行数据
  const selectedRows = ref<any[]>([])
  // 重置表单
  const handleReset = () => {
	if(userArtRuleSearchFormRef.value){
		userArtRuleSearchFormRef.value.resetForm();
		Object.assign(formFilters, { ...userArtRuleSearchFormRef.value.getFormData() })
		userArtRuleTableRef.value.reset(formFilters)
	}
  }

  // 搜索处理
  const handleSearch = () => {
	if(userArtRuleSearchFormRef.value){
		userArtRuleSearchFormRef.value.resetForm();
		Object.assign(formFilters, { ...userArtRuleSearchFormRef.value.getFormData() })
		userArtRuleTableRef.value.reset(formFilters)
	}
  }

//表单实例
const formRef = ref<FormInstance>()
const formData = reactive({
  id: '',
  name: '',
  category: '',
  type: '',
  description: '',
  thumbnail: '',
  path:'',
  configPath:'',
  thumbnailFile: null,
});
const BASE_API = axiosInstance.defaults.baseURL
const hovering = ref(false);
const imageUrl = computed(() =>
  formData.thumbnailFile
    ? URL.createObjectURL(formData.thumbnailFile)
    : (formData.thumbnail
        ? `${BASE_API}/visual/component/library/cover/${formData.thumbnail}?${new Date().getTime()}`
        : '')
);

const handleChange = (file: any) => {
  formData.thumbnailFile = file.raw;
};

const removeImage = () => {
  formData.thumbnailFile = null;
  formData.thumbnail = '';
};

const handlePreview = () => {
  if (imageUrl.value) {
    window.open(imageUrl.value, '_blank');
  }
};

// 表单验证规则
const rules = reactive<FormRules>({
	name: [
		{ required: true, message: '请输入组件名称', trigger: 'blur' },
		{ min: 2, max: 20, message: '长度在 2 到 50 个字符', trigger: 'blur' }
	],
	category: [
		{ required: true, message: '请选择组件分类', trigger: 'blur' }
	],
	type: [
		{ required: true, message: '请输入组件标识', trigger: 'blur' }
	],
	path: [
		{ required: true, message: '请输入组件路径', trigger: 'blur' },
		{ min: 2, max: 250, message: '长度在 2 到 250 个字符', trigger: 'blur' }
	],
	configPath: [
		{ min: 2, max: 250, message: '长度在 2 到 250 个字符', trigger: 'blur' }
	],
	description: [{ min: 0, max: 250, message: '最大长度250 个字符', trigger: 'blur' }]
})

const openDialog = async (type: string, row?: any) => {
  dialogVisible.value = true
  dialogType.value = type
  await getCategoriesOptions();
  clearForm();
  formRef.value?.resetFields();
  if (row) {
    formData.id = row.id;
    formData.name = row.name;
    formData.category = row.category;
    formData.type = row.type;
    formData.path = row.path;
    formData.configPath = row.configPath;
    formData.description = row.description;
    formData.thumbnail = row.thumbnail;
  }
}

const clearForm = () => {
  formData.id = '';
  formData.name = '';
  formData.category = '';
  formData.type = '';
  formData.path = '';
  formData.configPath = '';
  formData.description = '';
  formData.thumbnail = '';
  formData.thumbnailFile = null;
}

  const userArtRuleSearchFormRef=ref();
  const userArtRuleTableRef=ref();
  const editDataModelDialogRef = ref();
  const editDataModelDialogVisible = ref(false);
  // 处理表格行选择变化
  const handleSelectionChange = (selection: any[]) => {
    selectedRows.value = selection
  }
  /**
   * 规则实现
   */
  const fetchComponentLibraryData = async (): Promise<any[]> => {
    return ComponentLibraryService.pages({
  		query:formFilters,
		pageNumber:userArtRuleTableRef.value.pageNumber,
		pageSize:userArtRuleTableRef.value.pageSize,
      })
  }
  
  const customFormatters = {
	operate: (_value:any,row: any) => {
	  return h('div', [
	    h(ArtButtonTable, {
	      type: 'edit',
		  tip:true,
		  tipContent:'编辑',
	      onClick: () => openDialog('edit', row)
	    }),
		h(ArtButtonTable, {
		  icon:'&#xe77c;',
		  tip:true,
		  tipContent:'配置',
	      onClick: () => openConfigDialog(row)
	    }),
	    h(ArtButtonTable, {
	      type: 'delete',
		  tip:true,
		  tipContent:'删除',
	      onClick: () => deleteComponentLibrary(row)
	    })
	  ])
	}
  }
  
	const getToolBarFormatters = [
  	   {
		   type: 'add',
		   tip:true,
		   tipContent:'新增组件',
		   text:'新增组件',
		   onClick: () => openDialog('add')
	   }
	]
  
  const deleteComponentLibrary =  (row:any) => {
  	ElMessageBox.confirm('确定删除【'+row.name+'】组件吗？', '删除组件', {
  		confirmButtonText: '确定',
  		cancelButtonText: '取消',
  		type: 'error'
  	}).then(async () => {
  		loading.value = true
  		try {
  			await ComponentLibraryService.delete(row.id);
  			ElMessage.success('删除组件成功')
			userArtRuleTableRef.value.reload()
  		} catch {
  			ElMessage.error(`删除组件失败`)
  		}finally{
  			loading.value = false
  		}
  	})
  }
  
const handleSubmit = async () => {
  if (!formRef.value) return
  await formRef.value.validate(async (valid: any) => {
    if (valid) {
      loading.value = true
      try {
        const formDataToSend = objectToFormData(toRaw(formData));
        await ComponentLibraryService.save(formDataToSend)
        const message = dialogType.value === 'add' ? '新增成功' : '修改成功'
        ElMessage.success(message)
        userArtRuleTableRef.value.reload()
      } catch {
        ElMessage.error(`失败`)
      } finally {
        dialogVisible.value = false
        loading.value = false
      }
    }
  })
}
  
const openConfigDialog = (row: any) => {
  editDataModelDialogVisible.value = true;
  nextTick(() => {
    editDataModelDialogRef.value?.openDialog(row);
  });
}

const categories=ref<any[]>([]);
const getCategoriesOptions=async ()=>{
	const data= await DictService.getSelectOptions('visual-app-comp-type')
	categories.value=data
}
  
	onMounted(() => {
	})

const MAX_SIZE_MB = 1;
const beforeUpload = (file: File) => {
  const isLt1M = file.size / 1024 / 1024 < MAX_SIZE_MB;
  if (!isLt1M) {
    ElMessage.error('图片大小不能超过1MB！');
  }
  return isLt1M;
};

</script>

<style lang="scss" scoped>
  .account-page {
    :deep(.user) {
      .avatar {
        width: 40px;
        height: 40px;
        border-radius: 6px;
      }

      > div {
        margin-left: 10px;

        .user-name {
          font-weight: 500;
          color: var(--art-text-gray-800);
        }
      }
    }
  }
  .avatar-upload-wrapper {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    min-height: 140px;
  }
  .avatar-uploader {
    width: 130px;
    height: 130px;
    border-radius: 12px;
    // background: linear-gradient(135deg, #232a3a 60%, #1e90ff22 100%);
    box-shadow: 0 2px 16px #1e90ff22;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    position: relative;
    transition: box-shadow 0.3s, border 0.3s;
    border: 2px dashed #409eff88;
    overflow: hidden;
  }
  .avatar-uploader:hover {
    box-shadow: 0 6px 32px #409eff55;
    border: 2px solid #409eff;
  }
  .avatar-upload-placeholder {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    color: #8fa1c7;
    font-size: 16px;
    background: transparent;
    transition: background 0.2s;
  }
  .avatar-uploader-icon {
    font-size: 48px !important;
    color: #409effcc;
    margin-bottom: 8px;
    transition: color 0.2s;
  }
  .avatar-upload-text {
    font-size: 15px;
    color: #bfc6d1;
    letter-spacing: 1px;
  }
  .avatar-img-box {
    width: 100%;
    height: 100%;
    // border-radius: 12px;
    overflow: hidden;
    position: relative;
    box-shadow: 0 2px 16px #409eff33;
    // background: #181c24;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2px;
  }
  .avatar-img-box img.avatar {
    width: 100%;
    height: 100%;
    object-fit: contain;
  }
  .avatar-img-box:hover img.avatar {
    box-shadow: 0 6px 24px #409eff55;
  }
  .avatar-remove-btn {
    position: absolute;
    bottom: 10px;
    left: 50%;
    transform: translateX(-50%) scale(0.95);
    opacity: 0;
    transition: opacity 0.2s, transform 0.2s;
    z-index: 2;
    padding: 2px 18px;
    font-size: 14px;
    border-radius: 16px;
    background: rgba(255, 0, 0, 0.8);
    border: none;
  }
  .avatar-img-box:hover .avatar-remove-btn {
    opacity: 1;
    transform: translateX(-50%) scale(1.08);
  }
</style>
